<template>
    <div>
        <h2>HOME PAGE</h2>
        <p>{{msg}}</p>
        <p>{{name}}</p>
        <h4>{{state.counter}}</h4>
        <button @click="add">add</button>
        <button @click="sub">sub</button>
    </div>
</template>

<script>
import { reactive } from "vue"
export default {
    name: "Home",

    props:{
        msg: {
            default: "",
            type: String,
            required: true
        }
    },

    //setup函数 回调函数 不需要手动调用
    //setup其实就是组件的另外一个选项,但是setup可以用来替代之前所编写的大部分选项
    //methods,computed,watch,data,生命周期
    /*
    * 1.函数的参数
    *   props
    *       父组件传递过来的属性会被放到props对象中, 如果在setup中想要使用,那么就可以直接通过props获取
    *       1.和vue2一样,还是需要在props选项中定义, 其他用法和以前一样,可以直接在模版中使用
    *       2.在setup函数中要想使用props,那么不可通过this获取
    *       3.直接将props当作参数传递到setup函数中.
    *   context ==> setupContext
    *       1.attrs: 所有的非props的属性(attribute)
    *       2.slots: 父组件传递过来的插槽
    *       3.emit: 组件内部想要发送事件时,需要用到emit
    * */
    /*
    * 2.函数的返回值
    *   setup的返回值可以直接在模版template中使用
    *   也就是我们可以通过setup的返回值来代替data选项
    *       并且我们可以直接返回一个执行函数来代替在methods中定义的方法
    *   对于一个定义的变量来说,默认情况下,vue并不会跟踪他的变化, 也就是普通变量是没有响应式的
    * */

    /*
    * setup中为什么没有this
    * 1.在setup中你应该避免使用this,因为它不会找到组件实例.setup的调用发生在data\computed\methods被解析之前,它无法在setup中被获取
    *
    *   //vue3创建一个组件
    *   // createComponentInstance(app.vue)
    *   // 调用setupComponent() ==> 初始化Component内部操作 ==>{}
    *   // 取出setup函数并执行
    *   // 解析data\computed\methods
    *
    * */


    beforeCreate() {
        // this ==> Vue

    },
    created() {
        // this ==> comp
        // this.xxx
        // this.getDate()
    },

    date(){
        return{
            num:100
        }
    },


    // setup(props, context) {
    setup(props, {attrs, slots, emit}) {
        // this ==> 没有this
        console.log(props)
        console.log("context.attrs===>",attrs)
        console.log("context.slots===>",slots);
        console.log("context.emit===>",emit);
        // context.emit("事件名", "xxx");


        // reactive(函数)
        // 当我们使用reactive函数处理我们数据之后,数据再次被使用时会进行依赖收集
        // 当数据发生改变是,所有收集到的依赖都进行对应的响应式操作(比如更新页面)
        // 事实上,在vue2中我们所编写的data选项,其实也是在内部交给了reactive函数将其处理成响应时的

        let state = reactive({
            counter: 100
        })

        //reactiveAPI对传入的数据类型是有限制的, 他要求我们必须传入一个对象或者数组
        //如果说我们给reactive传入一个基本数据类型(string, number, boolean)会有一个警告
        //value cannot be made reactive: 100 当前这个值不能处理成响应式
        // let counter = reactive(100)

        let add = ()=>{
            console.log("add");
            state.counter++
        }
        let sub = ()=>{
            console.log("sub")
            state.counter--
        }

        return{
            name: "哈哈",
            state,
            add,
            sub
        }
    },
}
</script>

<style scoped>

</style>